package com.chen.authority.common.util;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.text.StrPool;
import cn.hutool.core.util.CharsetUtil;
import io.minio.*;
import io.minio.messages.DeleteObject;
import lombok.Cleanup;
import lombok.SneakyThrows;
import org.springframework.http.MediaType;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * minio 工具类
 *
 * @author chengy
 * @date 2024/9/16
 */
public class MinioUtil {

    private static final String endpoint = "http://localhost:9000";
    private static final String accessKey = "minioadmin";
    private static final String secretKey = "minioadmin";
    private static final String bucketName = "demo";
    private static final String url = endpoint + StrPool.SLASH + bucketName + StrPool.SLASH;

    private static final MinioClient minioClient = MinioClient.builder()
            .endpoint(endpoint)
            .credentials(accessKey, secretKey)
            .build();

    /**
     * 上传文件（适用于public策略的bucket）
     *
     * @param file 文件
     * @return 文件访问地址
     */
    @SneakyThrows
    public static String uploadFile(MultipartFile file) {
        String filename = System.currentTimeMillis() + StrPool.DOT + FileNameUtil.extName(file.getOriginalFilename());
        @Cleanup InputStream inputStream = file.getInputStream();
        PutObjectArgs putObjectArgs = PutObjectArgs.builder()
                .bucket(bucketName)
                .object(filename)
                .contentType(file.getContentType())
                .stream(inputStream, file.getSize(), -1)
                .build();
        minioClient.putObject(putObjectArgs);
        return url + filename;
    }

    @SneakyThrows
    public static void downloadFile(HttpServletResponse response, String filename) {
        GetObjectArgs getObjectArgs = GetObjectArgs.builder()
                .bucket(bucketName)
                .object(filename)
                .build();
        @Cleanup InputStream inputStream = minioClient.getObject(getObjectArgs);
        @Cleanup ServletOutputStream outputStream = response.getOutputStream();
        response.setHeader("Content-Disposition", "attachment;filename=" + filename);
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        response.setCharacterEncoding(CharsetUtil.UTF_8);
        IoUtil.copy(inputStream, outputStream);
    }

    /**
     * 删除文件
     *
     * @param filename 文件名
     */
    @SneakyThrows
    public static void deleteFile(String filename) {
        RemoveObjectArgs removeObjectArgs = RemoveObjectArgs.builder()
                .bucket(bucketName)
                .object(filename)
                .build();
        minioClient.removeObject(removeObjectArgs);
    }

    /**
     * 删除文件（批量）
     *
     * @param filenames 文件名列表
     * @return
     */
    public static void deleteFiles(List<String> filenames) {
        List<DeleteObject> deleteObjects = new ArrayList<>();
        for (String filename : filenames) {
            deleteObjects.add(new DeleteObject(filename));
        }
        RemoveObjectsArgs removeObjectsArgs = RemoveObjectsArgs.builder()
                .bucket(bucketName)
                .objects(deleteObjects)
                .build();
        minioClient.removeObjects(removeObjectsArgs);
    }
}